#ifndef CAPI_V2_PROPERTIES_H
#define CAPI_V2_PROPERTIES_H

/*
 * This file contrains the functions for controlling the
 * internal circular buffer within the sound trigger HAL.
 * The purpose is to keep all the different read and write
 * commands from different threads synchronized.
 *
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 @file capi_v2_properties.h
 Common Audio Processing Interface v2 header file

 This file defines the data structures and ids for getting and setting
 properties in the Common Audio Processing Interface.
 */
/* ========================================================================*/

#include "capi_v2_types.h"
#include "capi_v2_events.h"

/** @weakgroup weakf_capiv2_property_info
  Properties are used to set and get information to and from the module.
  Properties are identified by IDs and have corresponding payloads. Their usage
  is similar to parameters, but parameters are module specific:
  - Parameters are defined by the implementor of the module
  - Parameters are used to control aspects that are specific to the underlying
    algorithm
  - Properties are generic and are defined in the CAPIv2 interface. @vertspace{-6}

  @par Categories of properties
   - Properties that can be queried statically using
     capi_v2_get_static_properties_f(): @vertspace{2}
      - #CAPI_V2_INIT_MEMORY_REQUIREMENT
      - #CAPI_V2_STACK_SIZE
      - #CAPI_V2_MAX_METADATA_SIZE
      - #CAPI_V2_IS_INPLACE
      - #CAPI_V2_REQUIRES_DATA_BUFFERING
      - #CAPI_V2_NUM_NEEDED_FRAMEWORK_EXTENSIONS
      - #CAPI_V2_NEEDED_FRAMEWORK_EXTENSIONS
      - #CAPI_V2_MAX_STATIC_PROPERTIES
  @par
    - Properties that can be set at initialization and at any time after
      initialization: @vertspace{2}
      - #CAPI_V2_EVENT_CALLBACK_INFO
      - #CAPI_V2_PORT_NUM_INFO
      - #CAPI_V2_HEAP_ID
      - #CAPI_V2_INPUT_MEDIA_FORMAT
      - #CAPI_V2_LOG_CODE
      - #CAPI_V2_CUSTOM_INIT_DATA
      - #CAPI_V2_MAX_INIT_PROPERTIES
  @par
    - Properties that can be set only after initialization: @vertspace{2}
      - #CAPI_V2_ALGORITHMIC_RESET
      - #CAPI_V2_EXTERNAL_SERVICE_ID
      - #CAPI_V2_MAX_SET_PROPERTIES
  @par
    - Properties that can be queried using capi_v2_vtbl_t::get_properties():
      @vertspace{2}
      - #CAPI_V2_METADATA
      - #CAPI_V2_PORT_DATA_THRESHOLD
      - #CAPI_V2_OUTPUT_MEDIA_FORMAT_SIZE
      - #CAPI_V2_MAX_GET_PROPERTIES @newpage
  @par
    - Properties that can be set using capi_v2_vtbl_t::set_properties() and
      queried using capi_v2_vtbl_t::get_properties(): @vertspace{2}
      - #CAPI_V2_OUTPUT_MEDIA_FORMAT
      - #CAPI_V2_MAX_SET_GET_PROPERTIES
      - #CAPI_V2_MAX_PROPERTY
*/

/** @ingroup capiv2_property_ids
  Valid property IDs.
 */
enum capi_v2_property_id_t {
    //----------- Properties that can be queried statically using get_static_properties ---------------------------------
    CAPI_V2_INIT_MEMORY_REQUIREMENT,
    /**< Amount of memory (in bytes) to be passed into the capi_v2_init()
         function. @vertspace{4}

         Payload structure: capi_v2_init_memory_requirement_t @vertspace{6} */

    CAPI_V2_STACK_SIZE,
    /**< Stack size required by this module (in bytes). @vertspace{4}

         Payload structure: capi_v2_stack_size_t @vertspace{6} */

    CAPI_V2_MAX_METADATA_SIZE,
    /**< Maximum size of metadata generated by this module after each call
         to capi_v2_vtbl_t::process(). @vertspace{4}

         Payload structure: capi_v2_max_metadata_size_t @vertspace{4}

         If this value is zero, the module does not generate any metadata.
         The value includes the sizes of different structures used to pack
         metadata (see #CAPI_V2_METADATA). @vertspace{6} */

    CAPI_V2_IS_INPLACE,
    /**< Indicates whether the module can perform in-place computation.
         @vertspace{4}

         Payload structure: capi_v2_is_inplace_t @vertspace{4}

         If this value is TRUE, the caller can provide the same pointers for
         input and output (but this is not guaranteed). In this case, the input
         and output data format be the same, and the requires_data_buffering
         property be set to FALSE. @vertspace{6} */

    CAPI_V2_REQUIRES_DATA_BUFFERING,
    /**< Specifies whether data buffering is TRUE or FALSE. @vertspace{4}

         Payload structure: capi_v2_requires_data_buffering_t @vertspace{4}

         If this value is FALSE and the module does not require a port data
         threshold (#CAPI_V2_PORT_DATA_THRESHOLD), the module must behave as
         follows:
         @vertspace{6}
         - The number of output samples on all output ports must always be the
           same as the number of input samples. The caller must ensure that
           the number of input samples is the same on all input ports.
         - All of the input must be consumed. The caller must ensure that the
           output buffers have enough space.
         - The module must be able to handle any number of samples. @vertspace{6}
         @newpage

         If this value is FALSE and the module requires a port data threshold
          (#CAPI_V2_PORT_DATA_THRESHOLD), the module must behave as follows:
         @vertspace{6}
         - The number of samples per buffer on all input and output ports
           must be the same as the threshold.
         - The caller must call the module with the required number of samples.
         - All of the input must be consumed. The caller must ensure that the
           output buffers have enough space. @vertspace{6}

         If this value is TRUE, the module must behave as follows:
         @vertspace{6}
         - The module must define a threshold in number of bytes for each
           input port and each output port.
         - The module must consume data on its input ports and fill data on its
           output ports until one of the following occurs: @vertspace{4}
             - The amount of remaining data in each buffer of at least one
               input port is less than its threshold @vertspace{-2}
             - Or the amount of free space in each buffer of at least one
               output port is less than its threshold. @vertspace{6}

         When this value is set to TRUE, significant overhead is added. Use the
         TRUE setting only under the following circumstances: @vertspace{6}
         - The module performs encoding/decoding of data.
         - The module performs rate conversion between the input and output.
         @vertspace{6} */

    CAPI_V2_NUM_NEEDED_FRAMEWORK_EXTENSIONS,
    /**< Number of framework extensions required by this module. @vertspace{4}

         Payload structure: capi_v2_num_needed_framework_extensions_t
         @vertspace{6} */

    CAPI_V2_NEEDED_FRAMEWORK_EXTENSIONS,
    /**< List of framework extensions that are required by the module.
         @vertspace{4}

         Payload structure: An array of capi_v2_framework_extension_id_t
         structures @vertspace{6}
         - Each value is the ID of a framework extension.
         - The number of elements of the array is the number returned in the
           query for the #CAPI_V2_NUM_NEEDED_FRAMEWORK_EXTENSIONS property.
           @vertspace{6} */

    CAPI_V2_INTERFACE_EXTENSIONS,
    /**< List of interface extensions provided by the client.
         @vertspace{4}

         The module must set the is_supported flag to TRUE or FALSE to indicate
         whether the module supports this extension.
         Additional data can also be exchanged using an optional buffer per
         extension. @vertspace{4}

         Payload structure: capi_v2_interface_extns_list_t @vertspace{6} */

    CAPI_V2_MAX_STATIC_PROPERTIES = 0x10000,
    /**< Dummy value that indicates the range of properties.
         @vertspace{6} */

    //------------ End of properties that can be queried statically -------------------------

    //-------------- Properties that can be set at init and at any time after init ----------------------------
    CAPI_V2_EVENT_CALLBACK_INFO,
    /**< Function pointer and state required for raising events to the
         framework. @vertspace{4}

         Payload structure: capi_v2_event_callback_info_t @vertspace{6} */

    CAPI_V2_PORT_NUM_INFO,
    /**< Sets the number of input and output ports for the module.
         @vertspace{4}

         Payload structure: capi_v2_port_num_info_t @vertspace{6} */

    CAPI_V2_HEAP_ID,
    /**< Provides the heap IDs for allocating memory. @vertspace{4}

         Payload structure: capi_v2_heap_id_t @vertspace{6} */

    CAPI_V2_INPUT_MEDIA_FORMAT,
    /**< Sets the media format for an input port.
         The caller must set the port ID in the payload. @vertspace{4}

         Payload structure: capi_v2_set_get_media_format_t @vertspace{6} */

    CAPI_V2_LOG_CODE,
    /**< Provides the logging code to the module for logging module data.
         @vertspace{4}

         Payload structure: capi_v2_log_code_t @vertspace{6} */

    CAPI_V2_CUSTOM_INIT_DATA,
    /**< Provides module-specific initialization data.
         This property ID is typically set only at initialization time.
         @vertspace{4}

         Payload structure: Module-specific @vertspace{6} */

    CAPI_V2_SESSION_IDENTIFIER,
    /**< Provides values that allow the module to uniquely identify its
         placement and session.

         Payload structure: capi_v2_session_identifier_t @vertspace{6} */

    CAPI_V2_MAX_INIT_PROPERTIES = 0x20000,
    /**< Dummy value that indicates the range of properties.
         @vertspace{6} */

    //-------------- End of properties that can be set at init and at any time after init ----------------------

    //-------------- Properties that can only be set after init -------------
    CAPI_V2_ALGORITHMIC_RESET,
    /**< Specifies whether the module is to reset any internal buffers and the
         algorithm state to zero. @vertspace{4}

         Payload structure: Empty buffer @vertspace{4}

         Settings do not need to be reset, and memory allocated by the module
         does not need to be freed. @vertspace{6} */

    CAPI_V2_EXTERNAL_SERVICE_ID,
    /**< Currently not used. @vertspace{6} */

    CAPI_V2_REGISTER_EVENT_DATA_TO_DSP_CLIENT,
    /**< Specifies the registration information for an event of type
         #CAPI_V2_EVENT_DATA_TO_DSP_CLIENT. @vertspace{4}

         Payload structure: capi_v2_register_event_to_dsp_client_t @vertspace{6} */

    CAPI_V2_MAX_SET_PROPERTIES = 0x30000,
    /**< Dummy value that indicates the range of properties. @vertspace{6} */

    //-------------- End of properties that can be set any time -------------

    //-------------- Properties that can only be queried only using get properties ---------------
    CAPI_V2_METADATA,
    /**< Specifies that the module must fill in any metadata that it generated
         during a capi_v2_vtbl_t::process() call when the caller queries this
         parameter. The query is typically done after the module raises
         #CAPI_V2_EVENT_METADATA_AVAILABLE. @vertspace{4}

         Payload structure: capi_v2_metadata_t @vertspace{4}

         Metadata is put in the payload of capi_v2_metadata_t.
         The module must pack the payload of metadata as groups of
         asm_stream_param_data_t (defined in
         @xrefcond{Q3,80-NF774-1,80-NA610-1}). @vertspace{4}

         The buffer is structured as follows: @vertspace{6}
         - First asm_stream_param_data_v2_t
         - First metadata
         - Second asm_stream_param_data_v2_t
         - Second metadata
         - Etc. @vertspace{6} */
    /* asm_stream_param_data_t is in adsp_asm_stream_commands.h */

    CAPI_V2_PORT_DATA_THRESHOLD,
    /**< Threshold of an input or output port (in bytes). @vertspace{4}

         Payload structure: capi_v2_port_data_threshold_t @vertspace{4}

         This property ID is used only for modules that require a specific
         amount of data on any port. The module behavior depends on whether
         the module requires data buffering.
         For more information, see #CAPI_V2_REQUIRES_DATA_BUFFERING.
         @vertspace{6} */

    CAPI_V2_OUTPUT_MEDIA_FORMAT_SIZE,
    /**< Size of the media format payload for an output port.
         The size excludes the size of capi_v2_data_format_header_t.
         @vertspace{4}

         Payload structure: capi_v2_output_media_format_size_t @vertspace{6} */

    CAPI_V2_MAX_GET_PROPERTIES = 0x40000,
    /**< Dummy value that indicates the range of properties.
         @vertspace{6} */
    //------------ End of properties that can only be queried using get properties -------------------------

    //-------------- Properties that can be set or queried using set/get properties only ------------
    CAPI_V2_OUTPUT_MEDIA_FORMAT,
    /**< Queries the media format for a specified output port. @vertspace{4}

         Payload structure: capi_v2_set_get_media_format_t @vertspace{4}

         This property ID can also be used to set the output media format for
         modules that support control of the output media format. @vertspace{4}

         If a module supports control of some aspects such as the sample rate
         only, all other fields can be set to #CAPI_V2_DATA_FORMAT_INVALID_VAL.
         The caller must set the port ID in the payload. @vertspace{6} */

    CAPI_V2_CUSTOM_PROPERTY,
    /**< Sets and gets a property that is specific to a framework
          extension. This property ID can also be used to statically get a
          module-specific property. @vertspace{4}

          Payload structure: capi_v2_custom_property_t @vertspace{4}

          The framework extension must define a secondary property ID and
          corresponding payload structure (capi_v2_custom_property_t) that are
          specific to the information the property is to set or get.
          @vertspace{6} */

    CAPI_V2_MAX_SET_GET_PROPERTIES = 0x50000,
    /**< Dummy value that indicates the range of properties.
         @vertspace{6} */

    CAPI_V2_MAX_PROPERTY = 0x7FFFFFFF
    /**< Maximum value that a property ID can take. */

};

typedef enum capi_v2_property_id_t capi_v2_property_id_t;

typedef struct capi_v2_prop_t capi_v2_prop_t;

/** @addtogroup capiv2_data_types
@{ */
/** Contains properties that can be sent to a module.

  Properties are used for generic set and get commands, which are independent
  of the underlying module.
 */
struct capi_v2_prop_t {
    capi_v2_property_id_t id;
    /**< Unique identifier of the property that is being sent. */

    capi_v2_buf_t payload;
    /**< Payload buffer.

         The buffer must contain the payload corresponding to the property value
         for the set_property call, and it must be sufficiently large to contain
         the payload for a get_property call. */

    capi_v2_port_info_t port_info;
    /**< Information about the port for which the property is applicable.

         If the property is is applicable to any port, the is_valid flag must be
         set to FALSE in the port information. */
};

typedef struct capi_v2_proplist_t capi_v2_proplist_t;

/** Contains a list of CAPI_V2 properties. This structure can be used to send
  a list of properties to the module or query for the properties.
 */
struct capi_v2_proplist_t {
    uint32_t props_num;       /**< Number of elements in the array. */
    capi_v2_prop_t *prop_ptr; /**< Array of CAPI_V2 property elements. */
};
/** @} *//* end_addtogroup capiv2_data_types */

// Payloads for the properties
typedef struct capi_v2_init_memory_requirement_t capi_v2_init_memory_requirement_t;

/** @addtogroup capiv2_payload_structs
@{ */
/** Payload of the #CAPI_V2_INIT_MEMORY_REQUIREMENT property.
*/
struct capi_v2_init_memory_requirement_t {
    uint32_t size_in_bytes;  /**< Amount of memory. */
};

typedef struct capi_v2_stack_size_t capi_v2_stack_size_t;

/** Payload of the #CAPI_V2_STACK_SIZE property.
*/
struct capi_v2_stack_size_t {
    uint32_t size_in_bytes;  /**< Size of the stack. @newpagetable */
};

typedef struct capi_v2_max_metadata_size_t capi_v2_max_metadata_size_t;

/** Payload of the #CAPI_V2_MAX_METADATA_SIZE property.
*/
struct capi_v2_max_metadata_size_t {
    uint32_t output_port_index;  /**< Index of the output port for which this
                                      property applies. */
    uint32_t size_in_bytes;     /**< Size of the metadata. */
};

typedef struct capi_v2_is_inplace_t capi_v2_is_inplace_t;

/** Payload of the #CAPI_V2_IS_INPLACE property.
*/
struct capi_v2_is_inplace_t {
    bool_t is_inplace;
    /**< Indicates whether a module is capable of doing in-place processing.

         @values
         - 0 -- Does not support in-place processing
         - 1 -- Supports in-place processing @tablebulletend */
};

typedef struct capi_v2_requires_data_buffering_t capi_v2_requires_data_buffering_t;

/** Payload of the #CAPI_V2_REQUIRES_DATA_BUFFERING property.
*/
struct capi_v2_requires_data_buffering_t {
    bool_t requires_data_buffering;  /**< Specifies whether data buffering
                                          is set to TRUE. */
};

typedef struct capi_v2_event_callback_info_t capi_v2_event_callback_info_t;

/** Payload of the #CAPI_V2_EVENT_CALLBACK_INFO property.
*/
struct capi_v2_event_callback_info_t {
    capi_v2_event_cb_f event_cb; /**< Callback function used to raise an
                                      event. */
    void *event_context;         /**< Opaque pointer value used as the context
                                      for this callback function. */
};

typedef struct capi_v2_port_num_info_t capi_v2_port_num_info_t;

/** Payload of the #CAPI_V2_PORT_NUM_INFO property.
*/
struct capi_v2_port_num_info_t {
    uint32_t num_input_ports;   /**< Number of input ports. */
    uint32_t num_output_ports;  /**< Number of output ports. */
};

typedef struct capi_v2_heap_id_t capi_v2_heap_id_t;

/** Payload of the #CAPI_V2_HEAP_ID property.
*/
struct capi_v2_heap_id_t {
    uint32_t heap_id;  /**< Heap ID for allocating memory. */
};

typedef struct capi_v2_metadata_t capi_v2_metadata_t;

/** Payload of the #CAPI_V2_METADATA property.
*/
struct capi_v2_metadata_t {
    capi_v2_buf_t payload;  /**< For details, see #CAPI_V2_METADATA. */
};

typedef struct capi_v2_port_data_threshold_t capi_v2_port_data_threshold_t;

/** Payload of the #CAPI_V2_PORT_DATA_THRESHOLD property.
*/
struct capi_v2_port_data_threshold_t {
    uint32_t threshold_in_bytes;  /**< Threshold of an input or output port.
                                       */
};

typedef struct capi_v2_output_media_format_size_t capi_v2_output_media_format_size_t;

/** Payload of the #CAPI_V2_OUTPUT_MEDIA_FORMAT_SIZE property.
*/
struct capi_v2_output_media_format_size_t {
    uint32_t size_in_bytes;  /**< Size of the media format payload for an
                                  output port. */
};

typedef struct capi_v2_num_needed_framework_extensions_t capi_v2_num_needed_framework_extensions_t;

/** Payload of the #CAPI_V2_NUM_NEEDED_FRAMEWORK_EXTENSIONS property.
*/
struct capi_v2_num_needed_framework_extensions_t {
    uint32_t num_extensions;  /**< Number of framework extensions. */
};

typedef struct capi_v2_framework_extension_id_t capi_v2_framework_extension_id_t;

/** Payload of the #CAPI_V2_NEEDED_FRAMEWORK_EXTENSIONS property.
*/
struct capi_v2_framework_extension_id_t {
    uint32_t id;  /**< ID of the framework extension. */
};

typedef struct capi_v2_log_code_t capi_v2_log_code_t;

/** Payload of the #CAPI_V2_LOG_CODE property.
*/
struct capi_v2_log_code_t {
    uint32_t code;  /**< Code for logging module data. */
};

typedef struct capi_v2_session_identifier_t capi_v2_session_identifier_t;

/** Payload of the #CAPI_V2_SESSION_IDENTIFIER property.
 */
struct capi_v2_session_identifier_t {
    uint16_t service_id;
    /**< Unique identifier of the service in which the module is contained.

         This ID is an opaque value that is not guaranteed to be
         backward-compatible. As such, modules are not to determine their
         behavior based on this value. */

    uint16_t session_id;
    /**< Unique identifier of the session within the service as indicated by
         service_id.

         Modules can use this value together with service_id to generate unique
         IDs for setting up intermodule communication within the same service
         session or for debug messaging. */
};

typedef struct capi_v2_custom_property_t capi_v2_custom_property_t;

/** Payload of the #CAPI_V2_CUSTOM_PROPERTY property.
*/
struct capi_v2_custom_property_t {
    uint32_t secondary_prop_id;
    /**< Secondary property ID that indicates the format of the rest of the
         payload.

         Following this ID is the custom payload defined by the service. If a
         module does not support a custom property or a secondary property ID,
         it must return 0 in payload.actual_data_len of capi_v2_prop_t. */
};

typedef struct capi_v2_interface_extns_list_t capi_v2_interface_extns_list_t;

/** Payload of the #CAPI_V2_INTERFACE_EXTENSIONS property.

  Following this structure is an array of capi_v2_interface_extn_desc_t
  structures with num_extensions elements.
 */
struct capi_v2_interface_extns_list_t {
    uint32_t num_extensions;
    /**< Number of interface extensions for which the client is querying.
         The client must provide this value. */
};

typedef struct capi_v2_interface_extn_desc_t capi_v2_interface_extn_desc_t;

/** Data type of each element in an array of
    capi_v2_interface_extns_list_t::num_extensions elements (for the
    #CAPI_V2_INTERFACE_EXTENSIONS property).
 */
struct capi_v2_interface_extn_desc_t {
    uint32_t id;
    /**< ID of the interface extension being queried. The client must provide
         this value. */

    bool_t is_supported;
    /**< Indicates whether this extension is supported.

         @values
         - 0 -- Not supported
         - 1 -- Supported

         The module must provide this value. */

    capi_v2_buf_t capabilities;
    /**< Optional buffer containing a structure that can be used for further
         negotiation of capabilities related to this extension.

         The structure is defined in the interface extension file. If it is not
         defined in this file, the interface extension does not have a
         capabilities structure. */
};

typedef struct capi_v2_register_event_to_dsp_client_t capi_v2_register_event_to_dsp_client_t;

/** Payload of #CAPI_V2_REGISTER_EVENT_DATA_TO_DSP_CLIENT, which provides
    registration information for a #CAPI_V2_EVENT_DATA_TO_DSP_CLIENT event.
 */
struct capi_v2_register_event_to_dsp_client_t {
    uint32_t event_id;
    /**< ID of the event to be registered. */

    bool_t is_registered;
    /**< Indicates whether a client is registered for the event.

         @values
         - TRUE --  Client is registered
         - FALSE -- Client is not registered @tablebulletend */
};
/** @} *//* end_addtogroup capiv2_payload_structs */

#endif /* #ifndef CAPI_V2_PROPERTIES_H */
